package com.da.boot.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.write.metadata.WriteSheet;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;

/**
 * @Description: EasyExcelUtil工具类
 * @date: 2021/3/12 16:10
 */
public class EasyExcelUtil {

    /**
     * 读取Excel（多个sheet可以用同一个实体类解析）
     *
     * @param excelInputStream
     * @param fileName
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> readExcel(InputStream excelInputStream, String fileName, Class<T> clazz, int sheetNo,
                                        int headLineNum) {
        ExcelListener excelListener = new ExcelListener();
        ExcelReader excelReader = getReader(excelInputStream, fileName, clazz, excelListener);
        if (excelReader == null) {
            return new ArrayList<>();
        }
        List<ReadSheet> readSheetList = excelReader.excelExecutor().sheetList();
        //easyexcel对xlsx是从0开始计算sheet,xls是从1开始计算sheet
        if (!StrUtil.isBlank(fileName) && fileName.toLowerCase().endsWith("xlsx")) {
            sheetNo = sheetNo - 1;
        }
        for (ReadSheet readSheet : readSheetList) {
            readSheet.setSheetNo(sheetNo);
            readSheet.setHeadRowNumber(headLineNum);
            excelReader.read(readSheet);
        }
        excelReader.finish();
        return Convert.toList(clazz, excelListener.getDataList());
    }

    /**
     * 导出Excel(一个sheet)
     *
     * @param response  HttpServletResponse
     * @param list      数据list
     * @param fileName  导出的文件名
     * @param sheetName 导入文件的sheet名
     * @param clazz     实体类
     */
    public static <T> void writeExcel(HttpServletResponse response, List<T> list, String fileName, String sheetName,
                                      Class<T> clazz) {

        OutputStream outputStream = getOutputStream(response, fileName);
        ExcelWriter excelWriter = EasyExcel.write(outputStream, clazz).build();
        WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();
        excelWriter.write(list, writeSheet);
        excelWriter.finish();
    }

    /**
     * 导出时生成OutputStream
     */
    private static OutputStream getOutputStream(HttpServletResponse response, String fileName) {
        try {
            String fileSaveName = java.net.URLEncoder.encode(fileName, "UTF-8");
            response.reset();// 清空输出流
            // response.setContentType("application/octet-stream;charset=UTF-8");
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            response.addHeader("Content-Disposition", "filename=" + fileSaveName);
            response.setHeader("Pragma", "public");
            response.setHeader("Cache-Control", "no-store");
            response.addHeader("Cache-Control", "max-age=0");
            return response.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 导出Excel(一个sheet)
     *
     * @param file      文件
     * @param list      数据list
     * @param sheetName 导入文件的sheet名
     * @param clazz     实体类
     */
    public static <T> void writeExcelToFile(File file, List<T> list, String sheetName, Class<T> clazz) {
        ExcelWriter excelWriter = EasyExcel.write(file, clazz).build();
        WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();
        excelWriter.write(list, writeSheet);
        excelWriter.finish();
    }

    /**
     * 返回ExcelReader
     *
     * @param inputStream   文件
     * @param clazz         实体类
     * @param excelListener
     */
    private static <T> ExcelReader getReader(InputStream inputStream, String filename, Class<T> clazz,
                                             ExcelListener excelListener) {
        try {
            boolean isNotExcel = !filename.toLowerCase().endsWith(".xls") && !filename.toLowerCase().endsWith(".xlsx");
            if (filename == null || isNotExcel) {
                return null;
            }
            ExcelReader excelReader = EasyExcel.read(inputStream, clazz, excelListener).build();
            inputStream.close();
            return excelReader;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static <T> List<T> readSheetExcel(InputStream excelInputStream, String fileName, Class<T> clazz, int sheetNo,
                                             int headLineNum) {
        ExcelListener excelListener = new ExcelListener();
        ExcelReader excelReader = getReader(excelInputStream, fileName, clazz, excelListener);
        if (excelReader == null) {
            return new ArrayList<>();
        }
        List<ReadSheet> readSheetList = excelReader.excelExecutor().sheetList();
        //easyexcel对xlsx是从0开始计算sheet,xls是从1开始计算sheet
        if (!StrUtil.isBlank(fileName) && fileName.toLowerCase().endsWith("xlsx")) {
            sheetNo = sheetNo - 1;
        }
        ReadSheet readSheet = new ReadSheet();
        readSheet.setSheetNo(sheetNo);
        readSheet.setHeadRowNumber(headLineNum);
        excelReader.read(readSheet);
        excelReader.finish();
        return Convert.toList(clazz, excelListener.getDataList());
    }
}
